<template>
	<view class="chartBar">
		<canvas id="canvasBar" type='2d' ></canvas>
	</view>
</template>

<script>
export default {
	props: {
		barData: {
			type: Array,
			default: () => []
		}
	},
	data() {
		this.xMargin = 25;			// 两边距离
		this.lrMargin = 53;			// 中间柱子间距
		this.rectWidth = 16;		// 柱子宽度
		this.bgColor = "#1988F4";	// 柱子颜色
		this.fontHeight = 15;		// 文字高度
		return {
			
		}
	},
	mounted() {
		this.init();
	},
	methods: {
		// 初始化
		async init() {
			const query = wx.createSelectorQuery().in(this);
			query
				.select(`#canvasBar`)
				.fields({node: true, size: true})
				.exec( async res => {
					const canvas = res[0].node;
					const ctx = canvas.getContext('2d');
					this.ctx = ctx;
					this.charDom = res[0];
					// 通过分辨率重新设置
					const pixelRatio = await this.getSystemInfo();
					canvas.width = res[0].width * pixelRatio;
					canvas.height = res[0].height * pixelRatio;
					ctx.scale(pixelRatio, pixelRatio);
					// 处理数据刻度
					this.handleData();
					// 绘制y轴起始点
					this.MarkLine();
					// 绘制柱状
					this.drawBar();
				})
		},
		handleData() {
			const { ctx, charDom, barData } = this;
			let data = barData.reduce( (acc, item) => {
				acc.push(item.value);
				return acc;
			},[]);
			this.maxVal =  Math.max(...data),
			this.minVal =  Math.min(...data);
			if (this.minVal > 0) this.minVal = 0;
			if (this.minVal < 0 && this.maxVal < 0) this.maxVal = 0;
			// x轴刻度
			this.xScale();
			// y轴刻度
			this.ySCale(this.maxVal, this.minVal);
		},
		ySCale(maxVal, minVal) {
			const { charDom, fontHeight } = this;
			this.yMarkScale = (charDom.height - fontHeight * 2) / (maxVal - minVal);
		},
		xScale() {
			const { charDom, barData } = this;
			this.xMarkScale = charDom.width / barData.length;
		},
		MarkLine(pixelRatio) {
			const { ctx, charDom, barData, yMarkScale, xMarkScale, fontHeight, maxVal, minVal } = this;
			ctx.strokeStyle = '#f4f5f6';
			ctx.beginPath();
			ctx.moveTo(0, yMarkScale * maxVal + fontHeight);
			ctx.lineTo(charDom.width, yMarkScale * maxVal + fontHeight);
			ctx.stroke();
		},
		drawBar() {
			const { ctx, charDom, bgColor, barData, yMarkScale, xMarkScale, fontHeight, maxVal, minVal, rectWidth, xMargin, lrMargin } = this;
			ctx.fillStyle = bgColor;
			barData.forEach( (item,index) => {
				// 绘制矩形
				let x = xMargin + (rectWidth + lrMargin) * index;
				ctx.beginPath();
				ctx.rect(x, (maxVal - item.value) * yMarkScale + fontHeight, rectWidth, item.value * yMarkScale);
				ctx.fill();
				// 绘制文字
				ctx.save();
				ctx.font = `10px sans-serif`;
				let xPosition = item.value > 0 ? (x + rectWidth / 2 - ctx.measureText(item.value).width / 2) : (x + rectWidth / 2 - ctx.measureText(item.value).width / 2);
				ctx.fillText(item.value, xPosition, (maxVal - item.value) * yMarkScale + fontHeight + (item.value > 0 ? -2 : 10));
				ctx.restore();
				
				let data = barData.reduce( (acc, item) => {
					acc.push(item.value_yoy);
					return acc;
				},[]);
				let cMaxVal = Math.max(...data);
				let cMinVal = Math.min(...data);
				let cY = (charDom.height - fontHeight * 2) / (cMaxVal - cMinVal);
				ctx.save();
				ctx.fillStyle = '#FDAF5E';
				ctx.beginPath();
				ctx.arc(x + rectWidth / 2, (cMaxVal - item.value_yoy) * cY + fontHeight, 3, 0, 2 * Math.PI, false);
				ctx.fill();
				ctx.restore();
			})
			
			ctx.beginPath();
			ctx.strokeStyle = '#FDAF5E';
			barData.forEach( (item,index) => {
				let data = barData.reduce( (acc, item) => {
					acc.push(item.value_yoy);
					return acc;
				},[]);
				let cMaxVal = Math.max(...data);
				let cMinVal = Math.min(...data);
				let cY = (charDom.height - fontHeight * 2) / (cMaxVal - cMinVal);
				// 绘制矩形
				let x = xMargin + (rectWidth + lrMargin) * index;
				if (index == 0) {
					ctx.moveTo(x + rectWidth / 2, (cMaxVal - item.value_yoy) * cY + fontHeight);
				} else {
					ctx.lineTo(x + rectWidth / 2, (cMaxVal - item.value_yoy) * cY + fontHeight);
				}
			})
			ctx.stroke();
		},
		// 获取分辨率
		getSystemInfo() {
			return new Promise(resolve => {
				wx.getSystemInfo({
					success: cRes => {
						resolve(cRes ? cRes.pixelRatio : 2);
					}
				})
			})
		}
	}
}
</script>

<style lang="scss" scoped>
.chartBar, canvas {
	display: block;
	width: 100%;
	height: 100%;
}
</style>
